package graph;


import java.util.Arrays;
import java.util.Scanner;

/**
 * Prim:最小生成树
 * 题目描述
 * 在世界的某个区域，有一些分散的神秘岛屿，每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路，方便运输。
 * 不同岛屿之间，路途距离不同，国王希望你可以规划建公路的方案，如何可以以最短的总公路距离将 所有岛屿联通起来（注意：这是一个无向图）。
 * 给定一张地图，其中包括了所有的岛屿，以及它们之间的距离。以最小化公路建设长度，确保可以链接到所有岛屿。
 * 输入描述
 * 第一行包含两个整数V 和 E，V代表顶点数，E代表边数 。顶点编号是从1到V。例如：V=2，一个有两个顶点，分别是1和2。
 * 接下来共有 E 行，每行三个整数 v1，v2 和 val，v1 和 v2 为边的起点和终点，val代表边的权值。
 * 输出描述
 * 输出联通所有岛屿的最小路径总距离
 *
 * minDist数组 用来记录 每一个节点距离最小生成树的最近距离。
 * prim算法核心就是三步
 * 第一步，选距离生成树最近节点
 * 第二步，最近节点加入生成树
 * 第三步，更新非生成树节点到生成树的距离（即更新minDist数组）
 */
public class prim {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int v = sc.nextInt();
        int e = sc.nextInt();
        int[][] graph = new int[v + 1][v + 1];
        int[] mindist = new int[v + 1];
        for (int i = 1; i <= v; i++) {
            Arrays.fill(graph[i], Integer.MAX_VALUE);
        }
        Arrays.fill(mindist, 10001);
        boolean[] visited = new boolean[v + 1];
        for (int i = 0; i < e; i++) {
            int v1 = sc.nextInt();
            int v2 = sc.nextInt();
            int val = sc.nextInt();
            graph[v1][v2] = val;
            graph[v2][v1] = val;
        }

        for (int i = 1; i < v; i++) {
            int cur = -1;
            int min = Integer.MAX_VALUE;

            //1、选取最小生成树节点的条件：
            //  （1）不在最小生成树里
            //  （2）距离最小生成树最近的节点
            for (int j = 1; j <= v; j++) {
                if (!visited[j] && mindist[j] < min) {
                    cur = j;
                    min = mindist[j];
                }
            }

            // 2、prim三部曲，第二步：最近节点（cur）加入生成树
            visited[cur] = true;

            // 3、prim三部曲，第三步：更新非生成树节点到生成树的距离（即更新minDist数组）
            // cur节点加入之后， 最小生成树加入了新的节点，那么所有节点到 最小生成树的距离（即minDist数组）需要更新一下
            // 由于cur节点是新加入到最小生成树，那么只需要关心与 cur 相连的 非生成树节点 的距离 是否比 原来 非生成树节点到生成树节点的距离更小了呢
            for (int j = 1; j <= v; j++) {
                // 更新的条件：
                // （1）节点是 非生成树里的节点
                // （2）与cur相连的某节点的权值(此时cur已经是生成树里面的节点了，cur->j的距离小与mindist就可以更新) 比 该某节点距离最小生成树的距离小
                if (!visited[j] && graph[cur][j] < mindist[j]) {
                    mindist[j] = graph[cur][j];
                }
            }
        }
        int res = 0;
        for (int i = 2; i <= v; i++) {
            res += mindist[i];
        }
        System.out.println(res);
        sc.close();
    }
}
